# -*- coding: utf-8 -*-
"""
Created on Thu Jan 24 20:39:44 2019
视频：莫烦
https://morvanzhou.github.io/tutorials/machine-learning/torch/2-02-variable/

@author: Administrator
"""

import torch
#定义变量时必须使用的模块
from torch.autograd import Variable # torch 中 Variable 模块

#############。。。1.。。。################
# 先生鸡蛋
tensor = torch.FloatTensor([[1,2],[3,4]]) #注意里面是一个矩阵不要漏了一个大的[]
# 把鸡蛋放到篮子里, requires_grad是参不参与误差反向传播, 要不要计算梯度
# 默认requires_grad是False的，由于变量改变时会对自身下一次改变有影响，故设为True
variable = Variable(tensor, requires_grad=True)

print(tensor)
"""
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""

print(variable)
"""
Variable containing: #在spyder中没有这一句，这一句表示，这个变量是搭建图的一部分信息
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""

#############。。。2。。。。############
#tensor*tensor = [[1.,4.],[9.,16.]],torch.mean()之后，为（1+4+9+16)/4=7.5
t_out = torch.mean(tensor*tensor)       # x^2

v_out = torch.mean(variable*variable)   # x^2
print(t_out)
print(v_out)    # 7.5


############。。。。3.。。。###############
#反向传播了v_out，但是v_out是由variable计算来的，间接反向传播了variable，也影响了variable的梯度
v_out.backward()    # 模拟 v_out 的误差反向传递
'''
# 下面两步看不懂没关系, 只要知道 Variable 是计算图的一部分, 可以用来传递误差就好.
# v_out = 1/4 * sum(variable*variable) 这是计算图中的 v_out 计算步骤
#1/4 * sum(variable*variable)=sum(1/4*variable*variable),其中，sum相当于连加号，variable相当x，
#variable*variable相当于x的平方，然后1/4*variable*variable=1/4x^2,
#sum(1/4*variable*variable)就相当于一个级数，
# 针对于 v_out 的梯度就是, d(v_out)/d(variable) = 1/4*2*variable = variable/2
#即对一个级数求导，得到x/2
'''
print('grad:',variable.grad)    # 初始 Variable 的梯度
'''
 0.5000  1.0000
 1.5000  2.0000
'''

##########....4.......###################
print('variable',variable)     #  Variable 形式
"""
Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""

print('variable.data:',variable.data)    # tensor 形式
"""
 1  2
 3  4
[torch.FloatTensor of size 2x2]
"""
#不能直接variable.numpy()，变量不能直接变numpy,变量不是单纯的张量，
#variable.data才是一个纯张量
print(variable.data.numpy())    # numpy 形式
"""
[[ 1.  2.]
 [ 3.  4.]]
"""
